//
//  LibraryController.m
//  Bibliotecha
//
//  Created by Jaime Garnica on 4/18/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "LibraryController.h"



@implementation LibraryController

#pragma mark Accessor Methods

-(void)setLibraryPath: (NSString *)path
{
	[path retain];
	[libraryPath release];
	libraryPath = path;
	
	if( ![libraryPath isEqualToString:@"/"] )
	{
		[path release];
		libraryPath = [[libraryPath stringByAppendingString:@"/"] retain];
	}
}


-(NSString *)libraryPath
{
	return libraryPath;
}


-(void)setBigLibraryPath: (NSString *)path
{
	[path retain];
	[bigLibraryPath release];
	bigLibraryPath = path;
	
	if( ![bigLibraryPath isEqualToString:@"/"] )
	{
		[path release];
		bigLibraryPath = [[bigLibraryPath stringByAppendingString:@"/"] retain];
	}
}


-(NSString *)bigLibraryPath
{
	return bigLibraryPath;
}


-(void)setCurrentBook: (NSString *)book
{
	[book retain];
	[currentBook release];
	currentBook = book;
}


-(NSString *)currentBook
{
	return currentBook;
}
	

-(void)setSearch: (NSString *)aSearch
{
	[aSearch retain];
	[search release];
	search = aSearch;
}


-(void)setTypes: (NSMutableArray *)newTypes
{
	[newTypes retain];
	[types release];
	types = newTypes;
}


-(NSMutableArray *)types
{
	return types;
}


-(void)setCategories: (NSMutableArray *)newCategories
{
	[newCategories retain];
	[categories release];
	categories = newCategories;
}


-(NSMutableArray *)categories
{
	return categories;
}


-(void)setSubjects: (NSMutableArray *)newSubjects
{
	[newSubjects retain];
	[subjects release];
	subjects = newSubjects;
}


-(NSMutableArray *)subjects
{
	return subjects;
}


-(void)setBooks: (NSMutableArray *)newBooks
{
	[newBooks retain];
	[books release];
	books = newBooks;
}


-(NSMutableArray *)books
{
	return books;
}


-(void)setTheOutline: (PDFOutline *)anOutline
{
	[anOutline retain];
	[theOutline release];
	theOutline = anOutline;
}


-(PDFOutline *)theOutline
{
	return theOutline;
}


#pragma mark Library File Methods

-(void)createLibraryFile
{	
	NSXMLElement *root = [[NSXMLElement alloc] initWithName:@"library"];
	
	[libraryFile release];
	libraryFile = [[NSXMLDocument alloc] initWithRootElement:root];
	[libraryFile setVersion:@"1.0"];
	[libraryFile setCharacterEncoding:@"UTF-8"];
	
	[root release];
}


-(BOOL)loadLibraryFile
{
	NSData *aFile = [NSData dataWithContentsOfFile: [libraryPath stringByAppendingString:@"library.xml"]];
	
	if( aFile )
	{
		[libraryFile release];
		libraryFile = [[NSXMLDocument alloc] initWithData:aFile options:0 error:nil];
		return YES;
	}
	else return NO;
}


-(void)saveLibraryFile
{
	NSData *aFile;	//NSData to store the XML file
	
	aFile = [libraryFile XMLDataWithOptions:NSXMLNodePrettyPrint ];	//get the XML file
	
	[aFile writeToFile:[libraryPath stringByAppendingString:@"library.xml"] atomically:YES];	//save the XML file
} 


#pragma mark Book Filtering

-(void)updateTypes
{	
	NSString *xquery = [NSString stringWithFormat:@"for $x in /library/book where contains($x/title, \"%@\") order by $x/type return data($x/type)", search];
		
	NSArray *tempTypes = [[libraryFile rootElement] objectsForXQuery:xquery	error:nil];
		
	[self setTypes:[self makeUnique:tempTypes]];	//save the list of types
}


-(void)updateCategoriesOfType: (NSString *)type
{
	NSString *xquery = [NSString stringWithString:@"for $x in /library/book"];
		
	if( ![type isEqualToString:@""] )
	{
		xquery = [xquery stringByAppendingString:@" where $x/type = \""];
		xquery = [xquery stringByAppendingString:type];
		xquery = [xquery stringByAppendingString:@"\""];
	}
		
	if( [type isEqualToString:@""] )
	{
		xquery = [xquery stringByAppendingFormat:@" where contains($x/title, \"%@\")", search];
	}
	else xquery = [xquery stringByAppendingFormat:@" and contains($x/title, \"%@\")", search];
		
	xquery = [xquery stringByAppendingString:@" order by $x/category return data($x/category)"];
		
	NSArray *tempCategories = [[libraryFile rootElement] objectsForXQuery:xquery error:nil];
		
	[self setCategories:[self makeUnique:tempCategories]];
}


-(void)updateSubjectsOfCategory: (NSString *)category 
						andType: (NSString *)type
{	
	NSString *xquery = [NSString stringWithString:@"for $x in /library/book"];
		
	if( ![type isEqualToString:@""] && !(type == nil) )
	{
		xquery = [xquery stringByAppendingString:@" where $x/type = \""];
		xquery = [xquery stringByAppendingString:type];
		xquery = [xquery stringByAppendingString:@"\""];
	}
		
	if( ![category isEqualToString:@""] && !(category == nil) )
	{
		if( ![type isEqualToString:@""] )
			xquery = [xquery stringByAppendingString:@" and $x/category = \""];
			
		else
			xquery = [xquery stringByAppendingString:@" where $x/category = \""];
			
		xquery = [xquery stringByAppendingString:category];
		xquery = [xquery stringByAppendingString:@"\""];
	}
		
	if( ([category isEqualToString:@""] && [type isEqualToString:@""]) || ((category == nil) && (type == nil)) )
	{
		xquery = [xquery stringByAppendingFormat:@" where contains($x/title, \"%@\")", search];
	}
	else xquery = [xquery stringByAppendingFormat:@" and contains($x/title, \"%@\")", search];
		
	xquery = [xquery stringByAppendingString:@" order by $x/subject return data($x/subject)"];
		
	NSArray *tempSubjects = [[libraryFile rootElement] objectsForXQuery:xquery error:nil];
		
	[self setSubjects:[self makeUnique:tempSubjects]];
}


-(void)updateBooksOfSubject: (NSString *)subject
				andCategory: (NSString *)category
					andType: (NSString *)type
{
	NSString *xquery = [NSString stringWithString:@"for $x in /library/book"];
		
	if( ![type isEqualToString:@""] && !(type == nil) )
	{
		xquery = [xquery stringByAppendingString:@" where $x/type = \""];
		xquery = [xquery stringByAppendingString:type];
		xquery = [xquery stringByAppendingString:@"\""];
	}
		
	if( ![category isEqualToString:@""] && !(category == nil) )
	{	//if the category is not an empty string, add it to query
		if( ![type isEqualToString:@""] )
			xquery = [xquery stringByAppendingString:@" and $x/category = \""];
			
		else
			xquery = [xquery stringByAppendingString:@" where $x/category = \""];
			
		xquery = [xquery stringByAppendingString:category];
		xquery = [xquery stringByAppendingString:@"\""];
	}
		
	if( ![subject isEqualToString:@""] && !(subject == nil) )
	{
		if( [type isEqualToString:@""] && [category isEqualToString:@""] )
			xquery = [xquery stringByAppendingString:@" where $x/subject = \""];
		else
			xquery = [xquery stringByAppendingString:@" and $x/subject = \""];
			
		xquery = [xquery stringByAppendingString:subject];
		xquery = [xquery stringByAppendingString:@"\""];
	}
		
	if( ([category isEqualToString:@""] && [type isEqualToString:@""] && [subject isEqualToString:@""]) || ((subject == nil) && (category == nil) && (type == nil)) )
	{
		xquery = [xquery stringByAppendingFormat:@" where contains($x/title, \"%@\")", search];
	}
	else xquery = [xquery stringByAppendingFormat:@" and contains($x/title, \"%@\")", search];
		
	xquery = [xquery stringByAppendingString:@" order by $x/title return data($x/title)"];
		
	NSArray *tempBooks = [[libraryFile rootElement] objectsForXQuery:xquery error:nil];
		
	[self setBooks:[self makeUnique:tempBooks]];
}


-(NSArray *)returnBook: (NSString *)name
{
	NSMutableString *tempName = [NSMutableString stringWithCapacity:0];
	[tempName setString:name];
	[tempName replaceOccurrencesOfString:@"&" withString:@"&amp;" options:NSBackwardsSearch range:NSMakeRange(0, [tempName length])];
	[tempName replaceOccurrencesOfString:@"<" withString:@"&lt;" options:NSBackwardsSearch range:NSMakeRange(0, [tempName length])];
	
	NSString *xquery = [NSString stringWithString:@"for $x in /library/book where $x/title = \""];
	xquery = [xquery stringByAppendingString:tempName];
	xquery = [xquery stringByAppendingString:@"\" return $x"];
	
	//[[libraryFile rootElement] normalizeAdjacentTextNodesPreservingCDATA:NO];  //cuz documentation for objectForXQuery told me to
	
	NSError *error = nil;
	NSMutableArray *tempBook = [NSMutableArray arrayWithCapacity:9];
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSXMLNode *result = [[[libraryFile rootElement] objectsForXQuery:xquery error:&error] objectAtIndex:0];
	if(result)
	{
		[tempBook addObject:[[result childAtIndex:0] stringValue]];	//title
		[tempBook addObject:[[result childAtIndex:1] stringValue]];
		[tempBook addObject:[[result childAtIndex:2] stringValue]];
		[tempBook addObject:[[result childAtIndex:3] stringValue]];
		[tempBook addObject:[[result childAtIndex:4] stringValue]];
		[tempBook addObject:[[result childAtIndex:5] stringValue]];
		[tempBook addObject:[[result childAtIndex:6] stringValue]];
		[tempBook addObject:[[result childAtIndex:7] stringValue]];
		[tempBook addObject:[[result childAtIndex:8] stringValue]];
		[tempBook addObject:[NSNumber numberWithInt:[[[result childAtIndex:9] stringValue] intValue]]];
	}
	[pool release];
	return tempBook;
}


-(NSMutableArray *)makeUnique: (NSArray *)stuff
{
	NSMutableArray *thisIsUnique = [NSMutableArray arrayWithCapacity:1];
	
	unsigned int i, new;
	for( i = 0; i < [stuff count]; i++ )
	{
		if( i == 0 )
		{
			new = 0;
			[thisIsUnique insertObject:[stuff objectAtIndex:i] atIndex:new];
		}
		
		else
		{
			if( ![[stuff objectAtIndex:i] isEqualToString:[thisIsUnique objectAtIndex:new]])
			{
				new++;
				[thisIsUnique addObject:[stuff objectAtIndex:i]];	//if the entries are not equal, move
				//the new value to the unique array
			}
		}
	}
	
	if( [thisIsUnique count] > 0 )
	{
		if( ![[thisIsUnique objectAtIndex:0] isEqualToString:@""] )
		{
			[thisIsUnique insertObject:@"" atIndex:0];
		}
	}
	else
		[thisIsUnique insertObject:@"" atIndex:0];
	
	return thisIsUnique;
}


#pragma mark Book Modification

-(BOOL)insertNewBookWithName: (NSString *)name atPath: (NSString *)path
{	
	NSString *newPath = path;
	
	newPath = [[libraryPath stringByAppendingString:@"Biblio Library/"] stringByAppendingString:name];
	[[NSFileManager defaultManager] createDirectoryAtPath:[newPath stringByDeletingLastPathComponent] attributes:nil];
	
	if( [[NSUserDefaults standardUserDefaults] boolForKey:@"deleteOnAdd"] )
	{
		[[NSFileManager defaultManager] movePath:path toPath:newPath handler:nil];
	}
	
	else
	{
		[[NSFileManager defaultManager] copyPath:path toPath:newPath handler:nil];
	}
	
	newPath = [@"Biblio Library/" stringByAppendingString:name]; //keep location of books relative to libraryPath
	
	NSXMLElement *newBook = [[NSXMLElement alloc] initWithName:@"book"];
	
	[newBook addChild:[NSXMLNode elementWithName:@"title" stringValue:name]];
	[newBook addChild:[NSXMLNode elementWithName:@"author"]];
	[newBook addChild:[NSXMLNode elementWithName:@"year"]];
	[newBook addChild:[NSXMLNode elementWithName:@"type" stringValue:@"*Unfiled"]];
	[newBook addChild:[NSXMLNode elementWithName:@"category"]];
	[newBook addChild:[NSXMLNode elementWithName:@"subject"]];
	[newBook addChild:[NSXMLNode elementWithName:@"url"]];
	[newBook addChild:[NSXMLNode elementWithName:@"update"]];
	[newBook addChild:[NSXMLNode elementWithName:@"path" stringValue:newPath]];
	[newBook addChild:[NSXMLNode elementWithName:@"page"]];
	
	//calculate the md5 hash
	NSData *bookData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[libraryPath stringByAppendingString:newPath]]];
	unsigned char *digest = MD5([bookData bytes], [bookData length], NULL);
	NSString* hexgest = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
				   digest[0], digest[1], 
				   digest[2], digest[3],
				   digest[4], digest[5],
				   digest[6], digest[7],
				   digest[8], digest[9],
				   digest[10], digest[11],
				   digest[12], digest[13],
				   digest[14], digest[15]];
	
	[newBook addChild:[NSXMLNode elementWithName:@"md5" stringValue:hexgest]];
	
	NSXMLElement *library = [libraryFile rootElement];
	BOOL done = NO;
	unsigned int i = 0, numBooks = [library childCount];
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	while( (!done) && (i < numBooks ) )
	{
		if([[[[library childAtIndex:i] childAtIndex:0] stringValue] 
			compare: name options: NSCaseInsensitiveSearch /*| NSForcedOrderingSearch*/] == NSOrderedDescending )
		{
			[library insertChild:newBook atIndex:i];
			done = YES;
		}
		i++;
	}
	[pool release];
	
	if( (!done) && (i == numBooks) )
	{
		[[libraryFile rootElement] addChild:newBook];
	}
	
	[newBook release];
	return TRUE;
}


-(BOOL)removeBook: (NSString *)name toTrash: (BOOL)trash
{
	NSXMLElement *library = [libraryFile rootElement];
	
	unsigned int i = 0, numBooks = [library childCount];	//number of children (books)
	
	BOOL done = NO;
	
	NSArray *temp = [self returnBook:name];
	
	while( (!done) && (i < numBooks) )
	{
		if( [[[[library childAtIndex:i] childAtIndex:0] stringValue] isEqualToString: name] )
		{
			[library removeChildAtIndex:i];
			done = YES;
		}
		
		i++;
	}
	
	if( trash )
	{
		NSString *oldPath = [libraryPath stringByAppendingString:[temp objectAtIndex:8]];
		
		[[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation 
													 source:[oldPath stringByDeletingLastPathComponent] 
												destination:nil 
													  files:[NSArray arrayWithObject:[[temp objectAtIndex:8] lastPathComponent]] 
														tag:nil];	//magical method to move stuff to trash!
		[self checkForEmptyPath: oldPath];
	}

	return done;
}


-(BOOL)modifyBook: (NSString *)name withData: (NSArray *)data
{	
	[self removeBook:name toTrash:NO];
	
	NSString *newPath = [data objectAtIndex:8];
	
	if( ![[data objectAtIndex:3] isEqualToString:@""] && 
		![[data objectAtIndex:4] isEqualToString:@""] && 
		![[data objectAtIndex:5] isEqualToString:@""] )
	{
		NSString *oldPath = newPath;
		newPath = [NSString stringWithFormat:@"Biblio Library/%@/%@/%@/%@.pdf",
				   [data objectAtIndex:3], 
				   [data objectAtIndex:4], 
				   [data objectAtIndex:5], 
				   [data objectAtIndex:0]];
			
		[[NSFileManager defaultManager] createDirectoryAtPath:[[[[libraryPath stringByAppendingString:newPath] stringByDeletingLastPathComponent] 
																	stringByDeletingLastPathComponent] 
																   stringByDeletingLastPathComponent] attributes:nil];
		[[NSFileManager defaultManager] createDirectoryAtPath:[[[libraryPath stringByAppendingString:newPath] stringByDeletingLastPathComponent] 
																   stringByDeletingLastPathComponent] attributes:nil];
		[[NSFileManager defaultManager] createDirectoryAtPath:[[libraryPath stringByAppendingString:newPath] stringByDeletingLastPathComponent] attributes:nil];
		
		if( [[NSUserDefaults standardUserDefaults] boolForKey:@"deleteOnAdd"] )
		{
			[[NSFileManager defaultManager] movePath:[libraryPath stringByAppendingString:oldPath] toPath:[libraryPath stringByAppendingString:newPath] handler:nil];		
		}
		
		else
		{
			[[NSFileManager defaultManager] copyPath:[libraryPath stringByAppendingString:oldPath] toPath:[libraryPath stringByAppendingString:newPath] handler:nil];
		}
		
			
		[self checkForEmptyPath:[libraryPath stringByAppendingString:oldPath]];
	}
	
	NSXMLElement *newBook = [[NSXMLElement alloc] initWithName:@"book"];
	
	[newBook addChild:[NSXMLNode elementWithName:@"title" stringValue:[data objectAtIndex:0]]];
	[newBook addChild:[NSXMLNode elementWithName:@"author" stringValue:[data objectAtIndex:1]]];
	[newBook addChild:[NSXMLNode elementWithName:@"year" stringValue:[data objectAtIndex:2]]];
	[newBook addChild:[NSXMLNode elementWithName:@"type" stringValue:[data objectAtIndex:3]]];
	[newBook addChild:[NSXMLNode elementWithName:@"category" stringValue:[data objectAtIndex:4]]];
	[newBook addChild:[NSXMLNode elementWithName:@"subject" stringValue:[data objectAtIndex:5]]];
	[newBook addChild:[NSXMLNode elementWithName:@"url" stringValue:[data objectAtIndex:6]]];
	[newBook addChild:[NSXMLNode elementWithName:@"update" stringValue:[data objectAtIndex:7]]];
	[newBook addChild:[NSXMLNode elementWithName:@"path" stringValue:newPath]];
	
	NSXMLNode *newNode = [NSXMLNode elementWithName:@"page"];
	[newNode setObjectValue:[data objectAtIndex:9]];
	[newBook addChild:newNode];
	
	if( [data count] <= 10 )
	{
		//calculate the md5 hash
		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		NSData *bookData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[libraryPath stringByAppendingString:newPath]]];
		unsigned char *digest = MD5([bookData bytes], [bookData length], NULL);
		NSString* hexgest = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
							 digest[0], digest[1], digest[2], digest[3], digest[4], digest[5],
							 digest[6], digest[7], digest[8], digest[9], digest[10], digest[11],
							 digest[12], digest[13], digest[14], digest[15]];
		
		[newBook addChild:[NSXMLNode elementWithName:@"md5" stringValue:hexgest]];
		[pool release];
	}
	
	else
	{
		[newBook addChild:[NSXMLNode elementWithName:@"md5" stringValue:[data objectAtIndex:10]]];
	}
	
	NSXMLElement *library = [libraryFile rootElement];
	BOOL done = NO;
	unsigned int i = 0, numBooks = [library childCount];
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	while( (!done) && (i < numBooks ) )
	{
		if([[[[library childAtIndex:i] childAtIndex:0] stringValue] 
			compare: [data objectAtIndex:0] options: NSCaseInsensitiveSearch] == NSOrderedDescending )
		{
			[library insertChild:newBook atIndex:i];
			done = YES;
		}
		i++;
	}
	[pool release];
	
	if( (!done) && (i == numBooks) )
	{
		[[libraryFile rootElement] addChild:newBook];
	}
	
	[newBook release];
	return TRUE;
}


-(BOOL)storeCurrentDestination: (PDFView *)aDocument
{	
	if( currentBook )
	{
		NSArray *aBook = [self returnBook:currentBook];	//data for current book
		NSArray *updatedBook;
		
		updatedBook = [NSArray arrayWithObject:[aBook objectAtIndex:0]];
		
		unsigned int i;
		for( i=1; i<9; i++ )
		{
			updatedBook = [updatedBook arrayByAddingObject:[aBook objectAtIndex:i]];
		}
		
		PDFDocument *thePDF = [aDocument document];
		
		updatedBook = [updatedBook arrayByAddingObject:[NSNumber numberWithUnsignedInt:[thePDF indexForPage:[aDocument currentPage]]]];  
		
		[self modifyBook:currentBook withData:updatedBook];
	}
	return YES;
}


-(void)checkForEmptyPath: (NSString *)oldPath
{
	for( int j=0; j<3; j++ )
	{
		if( ![oldPath isEqualToString:[libraryPath stringByAppendingString:@"Biblio Library"]] )
			oldPath = [oldPath stringByDeletingLastPathComponent]; //now check to see if old directory is empty
		
		if( ![oldPath isEqualToString:[libraryPath stringByAppendingString:@"Biblio Library"]] )
		{
			NSArray *stuff = [[NSFileManager defaultManager] directoryContentsAtPath:oldPath];
			
			int stuffCount = [stuff count];
			for( int k=0; k<stuffCount; k++)
			{
				if( [[stuff objectAtIndex:k] characterAtIndex:0] == '.' )
				{
					stuffCount--;	//reduce the number of things at this path if any of them are invisible
				}
			}
			
			if( stuffCount == 0 )
			{
				[[NSFileManager defaultManager] removeFileAtPath:oldPath handler:nil];	//if directory is empty, remove it
			}
		}
	}
}


#pragma mark Library Synchronization

-(BOOL)loadBigLibraryFile		//loads the library file to synchronize to (bigLibraryFile)
{
	NSData *aFile = [NSData dataWithContentsOfFile: [bigLibraryPath stringByAppendingString:@"library.xml"]];
	
	if( aFile )
	{
		[bigLibraryFile release];
		bigLibraryFile = [[NSXMLDocument alloc] initWithData:aFile options:0 error:nil];
		return YES;
	}
	else return NO;
}
	
-(void)saveBigLibraryFile		//saves the library file to bigLibraryPath
{
	NSData *aFile;	//NSData to store the XML file
	
	aFile = [bigLibraryFile XMLDataWithOptions:NSXMLNodePrettyPrint ];	//get the XML file
	
	[aFile writeToFile:[bigLibraryPath stringByAppendingString:@"library.xml"] atomically:YES];	//save the XML file
}


-(BOOL)synchronizeLibraries		//moves any new books from the smaller library up to the larger
{
	NSXMLElement *smallLibRoot = [libraryFile rootElement];
	NSXMLElement *bigLibRoot = [bigLibraryFile rootElement];
	
	for( int i=0; i < [smallLibRoot childCount]; i++ )
	{
		bool isThere = FALSE;	//keep track of if the current book is present in the big library
		int placeItHere = -1;
		
		for( int j=0; j < [bigLibRoot childCount]; j++ )
		{
			if( [[[[bigLibRoot childAtIndex:j] childAtIndex:10] stringValue] isEqualToString: [[[smallLibRoot childAtIndex:i] childAtIndex:10] stringValue]] )
			{
				isThere = TRUE;
			}
			
			if( [[[[bigLibRoot childAtIndex:j] childAtIndex:0] stringValue] compare:[[[smallLibRoot childAtIndex:i] childAtIndex:0] stringValue]] == NSOrderedDescending )
			{
				if( placeItHere == -1 )
				{ 
					placeItHere = j;
				}
			}
		}
		
		if( !isThere )  //not is there, also known as not there
		{
			NSString *newPath = [[[smallLibRoot childAtIndex:i] childAtIndex:8] stringValue];
			//copy the actual file
			
			//create intermediate directories...
			NSString *tempPath3 = [[bigLibraryPath stringByAppendingString:newPath] stringByDeletingLastPathComponent];
			NSString *tempPath2 = [tempPath3 stringByDeletingLastPathComponent];
			NSString *tempPath1 = [tempPath2 stringByDeletingLastPathComponent];
			
			if( ![[tempPath3 lastPathComponent] isEqualToString:@"BiblioLibrary"] )
			{
				if( ![[tempPath2 lastPathComponent] isEqualToString:@"BiblioLibrary"] )
				{
					if( ![[tempPath1 lastPathComponent] isEqualToString:@"BiblioLibrary"] )
					{
						[[NSFileManager defaultManager] createDirectoryAtPath:tempPath1 attributes:nil];
					}
				}
			}
			
			if( ![[tempPath3 lastPathComponent] isEqualToString:@"BiblioLibrary"] )
			{
				if( ![[tempPath2 lastPathComponent] isEqualToString:@"BiblioLibrary"] )
				{
					[[NSFileManager defaultManager] createDirectoryAtPath:tempPath2 attributes:nil];
				}
			}
			
			if( ![[tempPath3 lastPathComponent] isEqualToString:@"BiblioLibrary"] )
			{
				[[NSFileManager defaultManager] createDirectoryAtPath:tempPath3 attributes:nil];
			}
			
			[[NSFileManager defaultManager] copyPath:[libraryPath stringByAppendingString:newPath] toPath:[bigLibraryPath stringByAppendingString:newPath] handler:nil];
			
			if( placeItHere != -1 )
			{
				NSXMLElement *temp = [[smallLibRoot childAtIndex:i] copy];
				[bigLibRoot insertChild:temp atIndex:placeItHere];
				[temp release];
			}
			
			else
			{
				[bigLibRoot addChild:[smallLibRoot childAtIndex:i]];
			}
		}
	}
	[self saveBigLibraryFile];
	return TRUE;
}

#pragma mark Method Overrides

-(void)dealloc
{
	[libraryFile release];
	[libraryPath release];
	[types release];
	[categories release];
	[subjects release];
	[books release];
	[currentBook release];
	[super dealloc];
}
	
@end
